import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;

import com.sun.j3d.utils.behaviors.vp.*;



public class GDVStuhlWS0405 extends Frame implements ActionListener
{


  public Canvas3D myCanvas3D; //The canvas to be drawn on.
  public Button myButton;     //The exit button.


  public GDVStuhlWS0405()
  {
    myButton = new Button("Exit");
    myCanvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());

    //The objects to be shown on the canvas are created in this method.
    BranchGroup theScene = createSceneGraph();

    //Put everything together in a simple universe:
    //The canvas to be drawn on
    SimpleUniverse simpUniv = new SimpleUniverse(myCanvas3D);

    //Move the viewer to a point so that the origin can be seen.
    simpUniv.getViewingPlatform().setNominalViewingTransform();



    //Add the objects in the scene.
    simpUniv.addBranchGraph(theScene);


    //To make it look nicer, a little bit of light is recommended.
    addLight(simpUniv);


    //This allows us to use the mouse to move the viewing platform.
    //Note that we have to import com.sun.j3d.utils.behaviors.vp.*;
    OrbitBehavior ob = new OrbitBehavior(myCanvas3D);
    ob.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0));
    simpUniv.getViewingPlatform().setViewPlatformBehavior(ob);





    View v = simpUniv.getViewer().getView();



    //Show the canvas
    setTitle("A chair");
    setSize(700,700);
    setLayout(new BorderLayout());
    add("Center", myCanvas3D);
    add("South",myButton);
    myButton.addActionListener(this);
    setVisible(true);

  }




  public static void main(String[] args)
  {
     GDVStuhlWS0405 sw = new GDVStuhlWS0405();
  }





  //Here we construct the scene
  public BranchGroup createSceneGraph()
  {


    float legHeight = 1.0f;
    float legThickness = 0.1f;
    float seatSize = 0.8f;
    float seatThickness = 0.2f;
    float backRadius = 0.4f;
    float backThickness = 0.2f;



    Color3f ambientColour = new Color3f(0.2f,0.2f,0.2f);
    Color3f emissiveColour = new Color3f(0.1f,0.1f,0.1f);
    Color3f diffuseColour = new Color3f(0.3f,0.3f,0.3f);
    Color3f specularColour = new Color3f(0.4f,0.4f,0.4f);
    float shininess = 100.0f;

    Appearance app = new Appearance();
    app.setMaterial(new Material(ambientColour,emissiveColour,diffuseColour,
                                  specularColour,shininess));


    //The seat
    Box seat = new Box(seatSize/2,seatThickness/2,seatSize/2,app);
    TransformGroup tgSeat = new TransformGroup();
    tgSeat.addChild(seat);


    //The back
    Cylinder back = new Cylinder(backRadius,backThickness,app);
    Transform3D tfBack = new Transform3D();
    tfBack.setTranslation(new Vector3d(0,backRadius+(seatThickness/2),
                                       -(seatSize/2)+(backThickness/2)));
    Transform3D rotationX = new Transform3D();
    rotationX.rotX(Math.PI/2);
    tfBack.mul(rotationX);
    TransformGroup tgBack = new TransformGroup(tfBack);
    tgBack.addChild(back);


    //The front left leg
    Box flLeg = new Box(legThickness/2,legHeight/2,legThickness/2,app);
    Transform3D tfFLLeg = new Transform3D();
    tfFLLeg.setTranslation(new Vector3d(-(seatSize/2)+(legThickness/2),
                                        -(legHeight/2)-(seatThickness)/2,
                                        (seatSize/2)-(legThickness/2)));
    TransformGroup tgFLLeg = new TransformGroup(tfFLLeg);
    tgFLLeg.addChild(flLeg);


    //The front right leg
    Box frLeg = new Box(legThickness/2,legHeight/2,legThickness/2,app);
    Transform3D tfFRLeg = new Transform3D();
    tfFRLeg.setTranslation(new Vector3d((seatSize/2)-(legThickness/2),
                                        -(legHeight/2)-(seatThickness)/2,
                                        (seatSize/2)-(legThickness/2)));
    TransformGroup tgFRLeg = new TransformGroup(tfFRLeg);
    tgFRLeg.addChild(frLeg);



   //The back left leg
    Box blLeg = new Box(legThickness/2,legHeight/2,legThickness/2,app);
    Transform3D tfBLLeg = new Transform3D();
    tfBLLeg.setTranslation(new Vector3d(-(seatSize/2)+(legThickness/2),
                                        -(legHeight/2)-(seatThickness)/2,
                                        -(seatSize/2)+(legThickness/2)));
    TransformGroup tgBLLeg = new TransformGroup(tfBLLeg);
    tgBLLeg.addChild(blLeg);


    //The back right leg
    Box brLeg = new Box(legThickness/2,legHeight/2,legThickness/2,app);
    Transform3D tfBRLeg = new Transform3D();
    tfBRLeg.setTranslation(new Vector3d((seatSize/2)-(legThickness/2),
                                        -(legHeight/2)-(seatThickness)/2,
                                        -(seatSize/2)+(legThickness/2)));
    TransformGroup tgBRLeg = new TransformGroup(tfBRLeg);
    tgBRLeg.addChild(brLeg);


    //The chair
    Transform3D tfChair = new Transform3D();
    tfChair.setTranslation(new Vector3d(0,legHeight+seatThickness/2,0));
    TransformGroup tgChair = new TransformGroup(tfChair);

    tgChair.addChild(tgSeat);
    tgChair.addChild(tgBack);
    tgChair.addChild(tgFLLeg);
    tgChair.addChild(tgFRLeg);
    tgChair.addChild(tgBLLeg);
    tgChair.addChild(tgBRLeg);






    // Create the root of the branch graph
    BranchGroup theScene = new BranchGroup();


    //Add the chair to the scene
    theScene.addChild(tgChair);


    //Create a white background. Do not forget to add it to the scene in the end.
    Background bg = new Background(new Color3f(1.0f,1.0f,1.0f));
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0),1000.0);
    bg.setApplicationBounds(bounds);

    theScene.addChild(bg);

    theScene.compile();

    return(theScene);
  }





  //To make the scene look a little bit more realistic we add some light
  public void addLight(SimpleUniverse su)
  {

    BranchGroup bgLight = new BranchGroup();

    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
    Color3f lightColour1 = new Color3f(1.0f,1.0f,1.0f);
    Vector3f lightDir1  = new Vector3f(-1.0f,0.0f,-0.5f);
    DirectionalLight light1 = new DirectionalLight(lightColour1, lightDir1);
    light1.setInfluencingBounds(bounds);

    bgLight.addChild(light1);


    Vector3f lightDir2  = new Vector3f(1.0f,0.0f,0.5f);
    DirectionalLight light2 = new DirectionalLight(lightColour1, lightDir2);
    light2.setInfluencingBounds(bounds);

    bgLight.addChild(light2);

    su.addBranchGraph(bgLight);
  }





  //Handles the exit button action to quit the program.
  public void actionPerformed(ActionEvent e)
  {
    dispose();
    System.exit(0);
  }

}
